<template>
  <div class="record-container">
    <div class="wave" ref="wave"></div>
    <div class="cancel-icon" @touchmove="move">
      <van-icon name="cross" />
    </div>
    <div class="start-btn" @touchstart="recStart" @touchend="recStop">
      <div class="text">松开 发送</div>
      <div class="btn-icon">
        <svg-icon class="icon" icon="wifi"></svg-icon>
      </div>
    </div>
  </div>
</template>

<script>
import Recorder from 'recorder-core/recorder.mp3.min'
import 'recorder-core/src/extensions/waveview'
import { mapActions } from 'vuex'
// https://github.com/xiangyuecn/Recorder
const recorderTimeMin = 200
export default {
  name: 'CahtRecord',
  data() {
    return {
      rec: null,
      wave: null,
      cancel: false,
      to: 'f450963b567747d092eeb90ca36a1aa5'
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    ...mapActions({ sendAudio: 'chatHistory/sendAudio' }),
    recOpen(success) {
      console.log('尝试打开recorder')
      // 一般在显示出录音按钮或相关的录音界面时进行此方法调用，后面用户点击开始录音时就能畅通无阻了
      this.rec = Recorder({
        type: 'mp3',
        sampleRate: 16000,
        bitRate: 16, // mp3格式，指定采样率hz、比特率kbps，其他参数使用默认配置；注意：是数字的参数必须提供数字，不要用字符串；需要使用的type类型，需提前把格式支持文件加载进来，比如使用wav格式需要提前加载wav.js编码引擎
        onProcess: (buffers, powerLevel, bufferDuration, bufferSampleRate, newBufferIdx, asyncEnd) => {
          // 录音实时回调，大约1秒调用12次本回调
          // 可利用extensions/waveview.js扩展实时绘制波形
          // 可利用extensions/sonic.js扩展实时变速变调，此扩展计算量巨大，onProcess需要返回true开启异步模式
          this.wave.input(buffers[buffers.length - 1], powerLevel, bufferSampleRate)
        }
      })
      // var dialog=createDelayDialog(); 我们可以选择性的弹一个对话框：为了防止移动端浏览器存在第三种情况：用户忽略，并且（或者国产系统UC系）浏览器没有任何回调，此处demo省略了弹窗的代码
      this.rec.open(
        () => {
          // 打开麦克风授权获得相关资源
          // dialog&&dialog.Cancel(); 如果开启了弹框，此处需要取消
          // rec.start() 此处可以立即开始录音，但不建议这样编写，因为open是一个延迟漫长的操作，通过两次用户操作来分别调用open和start是推荐的最佳流程
          console.log('打开成功调用回调')
          success && success()
        },
        (msg, isUserNotAllow) => {
          // 用户拒绝未授权或不支持
          // dialog&&dialog.Cancel(); 如果开启了弹框，此处需要取消
          console.log((isUserNotAllow ? 'UserNotAllow，' : '') + '无法录音:' + msg)
          this.$toast.fail('为获取录音权限，录音功能启动失败')
        }
      )
    },
    /** 开始录音**/
    recStart() {
      // 打开了录音后才能进行start、stop调用
      if (!this.rec) {
        // 重新打开
        this.recOpen(() => this.rec.start())
      } else {
        this.rec.start()
      }
    },

    /** 结束录音**/
    recStop(e) {
      if (this.cancel) {
        this.$toast('录音被取消了')
      }
      if (!this.rec) return
      this.rec.stop(
        async(blob, duration) => {
          this.cancel = false
          if (duration < recorderTimeMin) {
            this.$toast.fail('说话时间太短')
            return
          }
          this.$emit('recorder-end', { blob, duration })
        },
        msg => {
          console.log('录音失败:' + msg)
          this.rec.close() // 可以通过stop方法的第3个参数来自动调用close
          this.rec = null
        }
      )
    },
    move(e) {
      this.$toast('move-----')
    },
    init() {
      this.wave = Recorder.WaveView({ width: 200, height: 100 })
      this.$refs.wave.appendChild(this.wave.elem)
    },
    unload() {
      this.rec.close() // 释放录音资源，当然可以不释放，后面可以连续调用start；但不释放时系统或浏览器会一直提示在录音，最佳操作是录完就close掉
      this.rec = null
    }
  }
}
</script>

<style lang="scss" scoped>
.record-container {
  width: 100vw;
  height: calc(var(--vh) * 100);
  background-color: rgba(0, 0, 0, 0.45);
  position: fixed;
  top:0;
  left:0;
  z-index: 10;
  .wave {
    min-width: 200px;
    height: 100px;
    border-radius: 6px;
    background-color: #97EB62;
    position: absolute;
    left: 50%;
    top: 40%;
    transform: translateX(-50%);
  }

  .cancel-icon {
    color: $gray-5;
    position: absolute;
    width: 50px;
    height: 50px;
    border-radius: 50%;
    left: 50%;
    bottom: 170px;
    transform: translateX(-50%);
    text-align: center;
    font-size: 25px;
    background-color: $gray-8;
    &:active {
      background-color: $gray-7;
    }
    .van-icon {
      line-height: 50px;
    }
  }
  .start-btn {
    width: 100%;
    height: 150px;
    position: absolute;
    bottom: 0;
    background-color: #f7f7f7;;
    border-radius: 50% 50% 0 0/35px 35px 0 0;
    text-align: center;
    color: $gray-7;
    .text {
      padding-top: 10px;
      font-size: $font-size-md;
    }
    .btn-icon {
      margin-top: 20px;
      font-size: 30px;
      .icon {
        transform: rotate(90deg);
      }
    }
  }
}
</style>
